﻿// Extensions Made Easy - Copyright 2012 by Jan Van der Haegen - All rights reserved, use for educational purposes only.
using System;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;

namespace ExtensionsMadeEasy.ClientAPI.Utilities.Base
{
    public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged = delegate
        {
        };

        public void Refresh()
        {
            this.OnPropertyChanged(string.Empty);
        }

        public virtual void OnPropertyChanged(string propertyName)
        {
            this.RaisePropertyChangedEvent(propertyName);
        }

        public virtual void OnPropertyChanged<TProperty>(Expression<Func<TProperty>> property)
        {
            this.OnPropertyChanged(GetMemberInfo(property).Name);
        }

        internal void RaisePropertyChangedEvent(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        internal static MemberInfo GetMemberInfo(LambdaExpression lambda)
        {
            MemberExpression memberExpression = null;
            if (lambda.Body.NodeType == ExpressionType.Convert)
            {
                memberExpression = ((UnaryExpression)lambda.Body).Operand as MemberExpression;
            }
            else if (lambda.Body.NodeType == ExpressionType.MemberAccess)
            {
                memberExpression = lambda.Body as MemberExpression;
            }
            else if (lambda.Body.NodeType == ExpressionType.Call)
            {
                return ((MethodCallExpression)lambda.Body).Method;
            }

            return memberExpression.Member;
        }
    }
}